package com.reservation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.reservation.entity.Exhibition;
import com.reservation.entity.ExhibitionReservation;
import com.reservation.entity.Guide;
import com.reservation.entity.GuideReservation;
import com.reservation.entity.User;
import com.reservation.mapper.ExhibitionMapper;
import com.reservation.mapper.ExhibitionReservationMapper;
import com.reservation.mapper.GuideMapper;
import com.reservation.mapper.GuideReservationMapper;
import com.reservation.mapper.UserMapper;
import com.reservation.service.StatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 数据统计分析服务实现类
 */
@Service
public class StatisticsServiceImpl implements StatisticsService {

    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private ExhibitionMapper exhibitionMapper;
    
    @Autowired
    private ExhibitionReservationMapper exhibitionReservationMapper;
    
    @Autowired
    private GuideMapper guideMapper;
    
    @Autowired
    private GuideReservationMapper guideReservationMapper;

    @Override
    public Map<String, Object> getOverviewStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        // 获取用户总数
        Long userCount = userMapper.selectCount(null);
        result.put("userCount", userCount);
        
        // 获取展览总数
        Long exhibitionCount = exhibitionMapper.selectCount(null);
        result.put("exhibitionCount", exhibitionCount);
        
        // 获取预约总数（展览预约 + 解说员预约）
        Long exhibitionReservationCount = exhibitionReservationMapper.selectCount(null);
        Long guideReservationCount = guideReservationMapper.selectCount(null);
        result.put("reservationCount", exhibitionReservationCount + guideReservationCount);
        
        // 获取解说员总数
        Long guideCount = guideMapper.selectCount(null);
        result.put("guideCount", guideCount);
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getReservationTypeStatistics() {
        List<Map<String, Object>> result = new ArrayList<>();
        
        // 获取展览预约数量
        Long exhibitionReservationCount = exhibitionReservationMapper.selectCount(null);
        Map<String, Object> exhibitionReservation = new HashMap<>();
        exhibitionReservation.put("name", "展览预约");
        exhibitionReservation.put("value", exhibitionReservationCount);
        result.add(exhibitionReservation);
        
        // 获取解说员预约数量
        Long guideReservationCount = guideReservationMapper.selectCount(null);
        Map<String, Object> guideReservation = new HashMap<>();
        guideReservation.put("name", "解说员预约");
        guideReservation.put("value", guideReservationCount);
        result.add(guideReservation);
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getReservationStatusStatistics() {
        List<Map<String, Object>> result = new ArrayList<>();
        
        // 展览预约状态统计
        Map<String, Long> exhibitionStatusCount = getExhibitionReservationStatusCount();
        for (Map.Entry<String, Long> entry : exhibitionStatusCount.entrySet()) {
            Map<String, Object> statusItem = new HashMap<>();
            statusItem.put("name", getStatusDisplayName(entry.getKey()));
            statusItem.put("value", entry.getValue());
            result.add(statusItem);
        }
        
        // 解说员预约状态统计
        Map<String, Long> guideStatusCount = getGuideReservationStatusCount();
        for (Map.Entry<String, Long> entry : guideStatusCount.entrySet()) {
            // 检查结果中是否已存在该状态
            boolean exists = false;
            for (Map<String, Object> item : result) {
                if (item.get("name").equals(getStatusDisplayName(entry.getKey()))) {
                    // 已存在，累加数量
                    item.put("value", (Long) item.get("value") + entry.getValue());
                    exists = true;
                    break;
                }
            }
            
            // 不存在，添加新项
            if (!exists) {
                Map<String, Object> statusItem = new HashMap<>();
                statusItem.put("name", getStatusDisplayName(entry.getKey()));
                statusItem.put("value", entry.getValue());
                result.add(statusItem);
            }
        }
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getReservationTrendStatistics() {
        List<Map<String, Object>> result = new ArrayList<>();
        
        // 获取近30天的日期列表
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minusDays(29);
        
        // 创建日期格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        
        // 初始化日期映射，确保每一天都有数据
        Map<String, Long> dateCountMap = new LinkedHashMap<>();
        for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
            dateCountMap.put(date.format(formatter), 0L);
        }
        
        // 获取展览预约数据
        LambdaQueryWrapper<ExhibitionReservation> exhibitionQuery = new LambdaQueryWrapper<>();
        exhibitionQuery.ge(ExhibitionReservation::getReservationDate, startDate);
        exhibitionQuery.le(ExhibitionReservation::getReservationDate, endDate);
        List<ExhibitionReservation> exhibitionReservations = exhibitionReservationMapper.selectList(exhibitionQuery);
        
        // 按日期分组统计展览预约数量
        Map<String, Long> exhibitionDateCount = exhibitionReservations.stream()
                .collect(Collectors.groupingBy(
                        reservation -> reservation.getReservationDate().format(formatter),
                        Collectors.counting()
                ));
        
        // 获取解说员预约数据
        LambdaQueryWrapper<GuideReservation> guideQuery = new LambdaQueryWrapper<>();
        guideQuery.ge(GuideReservation::getReservationDate, startDate);
        guideQuery.le(GuideReservation::getReservationDate, endDate);
        List<GuideReservation> guideReservations = guideReservationMapper.selectList(guideQuery);
        
        // 按日期分组统计解说员预约数量
        Map<String, Long> guideDateCount = guideReservations.stream()
                .collect(Collectors.groupingBy(
                        reservation -> reservation.getReservationDate().format(formatter),
                        Collectors.counting()
                ));
        
        // 合并数据
        for (String dateStr : dateCountMap.keySet()) {
            Long exhibitionCount = exhibitionDateCount.getOrDefault(dateStr, 0L);
            Long guideCount = guideDateCount.getOrDefault(dateStr, 0L);
            Long totalCount = exhibitionCount + guideCount;
            
            Map<String, Object> dateItem = new HashMap<>();
            dateItem.put("name", dateStr);
            dateItem.put("value", totalCount);
            result.add(dateItem);
        }
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getPopularExhibitionStatistics(int limit) {
        // 获取所有展览
        List<Exhibition> exhibitions = exhibitionMapper.selectList(null);
        
        // 统计每个展览的预约次数
        Map<Long, Long> exhibitionReservationCount = new HashMap<>();
        for (Exhibition exhibition : exhibitions) {
            LambdaQueryWrapper<ExhibitionReservation> query = new LambdaQueryWrapper<>();
            query.eq(ExhibitionReservation::getExhibitionId, exhibition.getId());
            Long count = exhibitionReservationMapper.selectCount(query);
            exhibitionReservationCount.put(exhibition.getId(), count);
        }
        
        // 按预约次数排序，取前limit个
        List<Map<String, Object>> result = exhibitions.stream()
                .sorted((e1, e2) -> exhibitionReservationCount.get(e2.getId()).compareTo(exhibitionReservationCount.get(e1.getId())))
                .limit(limit)
                .map(exhibition -> {
                    Map<String, Object> item = new HashMap<>();
                    item.put("name", exhibition.getName());
                    item.put("value", exhibitionReservationCount.get(exhibition.getId()));
                    return item;
                })
                .collect(Collectors.toList());
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getPopularGuideStatistics(int limit) {
        // 获取所有解说员
        List<Guide> guides = guideMapper.selectList(null);
        
        // 统计每个解说员的预约次数
        Map<Long, Long> guideReservationCount = new HashMap<>();
        for (Guide guide : guides) {
            LambdaQueryWrapper<GuideReservation> query = new LambdaQueryWrapper<>();
            query.eq(GuideReservation::getGuideId, guide.getId());
            Long count = guideReservationMapper.selectCount(query);
            guideReservationCount.put(guide.getId(), count);
        }
        
        // 按预约次数排序，取前limit个
        List<Map<String, Object>> result = guides.stream()
                .sorted((g1, g2) -> guideReservationCount.get(g2.getId()).compareTo(guideReservationCount.get(g1.getId())))
                .limit(limit)
                .map(guide -> {
                    Map<String, Object> item = new HashMap<>();
                    item.put("name", guide.getName());
                    item.put("value", guideReservationCount.get(guide.getId()));
                    return item;
                })
                .collect(Collectors.toList());
        
        return result;
    }
    
    /**
     * 获取展览预约状态统计
     */
    private Map<String, Long> getExhibitionReservationStatusCount() {
        List<ExhibitionReservation> reservations = exhibitionReservationMapper.selectList(null);
        return reservations.stream()
                .collect(Collectors.groupingBy(ExhibitionReservation::getStatus, Collectors.counting()));
    }
    
    /**
     * 获取解说员预约状态统计
     */
    private Map<String, Long> getGuideReservationStatusCount() {
        List<GuideReservation> reservations = guideReservationMapper.selectList(null);
        return reservations.stream()
                .collect(Collectors.groupingBy(GuideReservation::getStatus, Collectors.counting()));
    }
    
    /**
     * 获取状态显示名称
     */
    private String getStatusDisplayName(String status) {
        switch (status) {
            case "PENDING":
                return "待审核";
            case "APPROVED":
                return "已通过";
            case "REJECTED":
                return "已拒绝";
            case "CANCELED":
                return "已取消";
            case "COMPLETED":
                return "已完成";
            default:
                return status;
        }
    }
}